import express from 'express';
import Cors from 'cors';
import { Nuxt, Builder } from 'nuxt';
import Session from 'express-session';
import bodyParser from 'body-parser';
import proxyMiddleware from 'http-proxy-middleware';
import $ from './config';

const axios = require('axios');
const app = express();
const server = require('http').Server(app);
const signature = require('cookie-signature');

/***
 * 搭建 websocket 服务器
 **/
const io = require('socket.io')(server);
io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});
console.log('socket listening!'); // eslint-disable-line no-console

function modify (config) {
  let originStep = [];
  config.cors.origin.forEach(item => {
    originStep.push(new RegExp(item));
  });
  config.cors.origin = originStep;
  return config;
}

let Config = modify($);

let {
  Java,
  Local,
  cors,
  LocalURL,
  session,
  SSO,
} = Config;

const host = process.env.HOST || LocalURL.origin;
const port = process.env.PORT || LocalURL.port;

app.set('port', port);

/***
   * Enable All CORS Requests
   **/
/*
app.use(Cors({
  credentials: true,
  origin: [/^http:\/\/192\.168.*!/, 'null'],
}));
*/

app.use(Cors(cors));

/***
   * 启用 session
   **/
app.use(Session(session));

/***
   * 转发系统
   **/
const JavaName = '/' + Java.projectName;
app.use(JavaName, function (req, res, next) {
  if (req.session.JSESSIONID) {
    return next();
  } else {
    console.error('没有JSESSIONID的用户访问' + (new Date()).toLocaleTimeString());
    return res.json({'messageType': 1, 'type': 'error', 'title': '提示信息', 'message': '请先登录', 'url': '/'});
  }
});
app.use(proxyMiddleware(JavaName, {
  target: Java.originUrl,
  secure: false,
  changeOrigin: false,
  onProxyReq (proxyReq, req, res) {
    proxyReq.setHeader('client_ip', req.ip);
    proxyReq.setHeader('cookie', `JSESSIONID=${req.session.JSESSIONID};`);
  },
}));

// -------------------------------------------------------------------
//                          模拟 业务层
app.use(bodyParser.json()); // 请求解析 为json格式
app.use(bodyParser.urlencoded({extended: true}));

// -------------------------------------------------------------------

/***
 * 全局拦截器
 **/
const userInfoFilter = new RegExp(`^/${Local.name}/${Local.userInfo}`);
const loginFilter = new RegExp('(.*/login$)|(.*/login?)');

app.use(async function (req, res, next) {
  if (req.query.ticket && req.query.ckcode) {
    let responseUrl = `${Java.url}/${Local.userInfo}?ticket=${req.query.ticket || 'ticket'}&ckcode=${req.query.ckcode || 'ckcode'}&appcode=${Local.appCode}`;
    try {
      let response = await axios({
        method: 'get',
        // url: ssoLogin,
        url: responseUrl,
        headers: {
          'client_ip': req.ip,
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
          'Content-Type': 'application/json;charset=UTF-8',
        },
      });
      let {type} = response.data;
      if (type) {
        console.error('未登录的用户!   ' + (new Date()).toLocaleTimeString());
      } else {
        req.session.JSESSIONID = response.headers['set-cookie'][0].split(';')[0].split('=')[1];
        if (req.session.JSESSIONID) {
          req.session.save();
          if (userInfoFilter.test(req.url)) {
            return res.send(response.data);
          } else {
            req.headers.cookie = `${Local.appCode}=${'s:' + signature.sign(req.session.id, session.secret)};`;
          }
        } else {
          console.error('存在异常 JSESSIONID !   ' + (new Date()).toLocaleTimeString());
          return res.send(response.data);
        }
      }
    } catch (err) {
      console.error('后台未响应' + (new Date()).toLocaleTimeString());
      return res.json({
        'messageType': 1,
        'type': 'error',
        'title': '提示信息',
        'message': '请先登录',
        'url': '/',
      });
    }
  }
  if (typeof req.query.userLogin !== 'undefined') {
    delete req.session.JSESSIONID;
    return next();
  }

  let path = req.url.split('/');
  let appCode = path[1];
  if (appCode && appCode !== Local.name) {
    return next();
  }

  if (userInfoFilter.test(req.url) && req.session.JSESSIONID) {
    try {
      let response = await axios({
        method: 'get',
        // url: ssoLogin,
        url: `${Java.url}/${Local.userInfo}`,
        headers: {
          'client_ip': req.ip,
          'Cookie': `JSESSIONID=${req.session.JSESSIONID};`,
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
          'Content-Type': 'application/json;charset=UTF-8',
        },
      });
      return res.send(response.data);
    } catch (err) {

    } finally {

    }
  }

  if (loginFilter.test(req.url) && typeof req.session.JSESSIONID !== 'undefined') {
    return res.redirect(Local.url);
  } else if (typeof req.session.JSESSIONID !== 'undefined') {
    return next();
  } else {
    return res.redirect(`${SSO.ssoOrigin + SSO.checkTicket}?url=${req.url}&login=${Local.url + '/login'}&appcode=${Local.appCode}`);
  }
});

// Import and Set Nuxt.js options
let config = require('../nuxt.config.js');
config.dev = !(process.env.NODE_ENV === 'production');

// Init Nuxt.js
const nuxt = new Nuxt(config);

// Build only in dev mode
if (config.dev) {
  const builder = new Builder(nuxt);
  builder.build();
}

// Give nuxt middleware to express
app.use(nuxt.render);

// Listen the server
server.listen(port, host);
console.log('Server listening on ' + host + ':' + port); // eslint-disable-line no-console
